package lumis.service.portalmanagement.servicesearchindex;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import org.w3c.dom.Node;

import lumis.doui.DouiException; 
import lumis.doui.DouiManagerFactory;
import lumis.doui.source.IDataProvider;
import lumis.doui.source.ISourceContext;
import lumis.doui.source.ISourceData;
import lumis.doui.source.Source;
import lumis.doui.source.SourceContext;
import lumis.doui.source.SourceFactory;
import lumis.doui.source.TabularData;
import lumis.doui.source.TabularSource;
import lumis.doui.source.field.ITabularSourceField;
import lumis.portal.PortalException;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.localization.ILocalizationManager;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.service.ServiceConfig;
import lumis.portal.serviceinstance.ServiceInstanceConfig;
import lumis.util.IResource;
import lumis.util.ITransaction;
import lumis.util.XmlUtil;

/**
 * Provides a list of searchable and instantiated services and respective service instances 
 *
 * @version $Revision: 11114 $ $Date: 2009-11-24 19:15:40 -0200 (Tue, 24 Nov 2009) $
 * @since 4.0.7
 */
public class ServiceSearchIndexDataProvider implements IDataProvider
{
	@SuppressWarnings("unchecked")
	public void loadData(SessionConfig sessionConfig, Source source, ITransaction transaction) throws PortalException
	{
		TabularSource<ITabularSourceField> tabularSource = (TabularSource<ITabularSourceField>) source;

		// get the field names
		boolean showServiceInstances = false;
		ArrayList<String> fieldIds = new ArrayList<String>();
		for (ITabularSourceField field : tabularSource.getFields())
		{
			fieldIds.add(field.getId());
			if ("serviceInstanceId".equals(field.getId()))
				showServiceInstances = true;
		}

		ILocalizationManager localizationManager = ManagerFactory.getLocalizationManager();
		IResource resource;

		TabularData tabularData = (TabularData) source.getData();

		// filter by service, if requested
		String serviceIdParameter = (String) tabularSource.getParameterValue("serviceId");
		Collection<ServiceConfig> serviceConfigs = null;
		if (serviceIdParameter != null)
			serviceConfigs = Arrays.asList(new ServiceConfig[] { ManagerFactory.getServiceManager().get(sessionConfig, serviceIdParameter, transaction) });
		else
			serviceConfigs = ManagerFactory.getServiceManager().getServices(sessionConfig, false, transaction);

		// for each service
		for (ServiceConfig serviceConfig : serviceConfigs)
		{
			
			Collection<String> serviceInstanceIds = ManagerFactory.getServiceInstanceManager().getIdsByServiceId(sessionConfig, serviceConfig.getId(), transaction);
			if (serviceInstanceIds.isEmpty())
				continue;
			
			ServiceInstanceConfig serviceInstanceConfig = ManagerFactory.getServiceInstanceManager().get(serviceInstanceIds.iterator().next(), transaction); 

			ISourceContext sourceContext = new SourceContext(sessionConfig, serviceInstanceConfig, transaction);

			// for each service's source
			Node douiServiceDefinitionNode = null;

			try
			{
				douiServiceDefinitionNode = DouiManagerFactory.getDouiManager().getDouiServiceDefinitionNode(serviceConfig.getId(), transaction);
			}
			catch (DouiException e)
			{
			}
			boolean isSearchable = false;
			if (douiServiceDefinitionNode != null)
			{
				for (Node sourceDefinitionNode : XmlUtil.selectNodes("service/sources/source", douiServiceDefinitionNode))
				{
					TabularSource serviceSource = (TabularSource) SourceFactory.createSource(sourceDefinitionNode, sourceContext);
					if (serviceSource.isSearchEnabled() && serviceSource.getSearchableFields().size() > 0)
					{
						isSearchable = true;
						break;
					}
				}
			}
			if (isSearchable)
			{
				resource = serviceConfig.getResource();
				String name = localizationManager.localize(serviceConfig.getName(), resource);

				if (showServiceInstances)
				{
					for (String serviceInstanceId : ManagerFactory.getServiceInstanceManager().getIdsByServiceId(sessionConfig, serviceConfig.getId(), transaction))
					{
						ServiceInstanceConfig searchableServiceInstanceConfig = ManagerFactory.getServiceInstanceManager().get(serviceInstanceId, transaction);
						StringBuilder serviceInstanceName = new StringBuilder();
						for (String channelId : ManagerFactory.getChannelManager().getPathIds(sessionConfig, searchableServiceInstanceConfig.getChannelId(), transaction))
						{
							serviceInstanceName.append(ManagerFactory.getChannelManager().get(sessionConfig, channelId, transaction).getName());
							serviceInstanceName.append(" / ");
						}
						serviceInstanceName.append(searchableServiceInstanceConfig.getName());
						ISourceData row = tabularData.addRow();
						row.put("serviceInstanceId", serviceInstanceId);
						row.put("serviceInstanceName", serviceInstanceName.toString());
						row.put("serviceId", serviceConfig.getId());
						row.put("serviceName", name);
					}
				}
				else
				{
					ISourceData row = tabularData.addRow();
					row.put("serviceId", serviceConfig.getId());
					row.put("serviceName", name);
				}
			}
		}

		tabularData.sort(tabularSource);
	}
}
